# This file is used to create a login blueprint for the flask application.
# The blueprint is used to handle the login functionality of the application.


from flask import Blueprint
from flask import request
from flask import jsonify
import psycopg2.extras
from settings import *
from database import PostgreSingleton
from database.wx_login_methods import WxLoginMethods
from database.wx_token_table_methods import WxTokenTableMethods
from database.wx_user_table_methods import WxUserTableMethods
from database.wx_access_token import WxAccessTokenTableMethods
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

wx_login_blueprint = Blueprint('wx_login_blueprint', __name__)


@wx_login_blueprint.route('/tt_login', methods=['POST'])
def tt_login():

    # Get the required arguments from the request

    js_code = request.form.get('js_code')

    # Check if the required arguments are present
    if not js_code:
        args_error = {
            "status": -1,
            "errorCode": 1001,
            "errorMsg": "js_code is required",
            "resultBody": None

        }

        return jsonify(args_error)

    # Check if the user exists in the database
    with PostgreSingleton() as conn:
        cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) # cursor for executing queries
        wx_login_methods = WxLoginMethods(conn, cur)
        
        js_code_result = wx_login_methods.wx_jscode2session(js_code)

        if not js_code_result or js_code_result.get("errcode") != 0:
            args_error = {
                "status": -1,
                "errorCode": 1002,
                "errorMsg": "jscode2session API call failed",
                "resultBody": js_code_result
            }

            return jsonify(args_error)
        
        
        user_info = WxUserTableMethods(conn, cur).get_user_by_open_id(js_code_result["openid"])

        if not user_info:
            WxUserTableMethods(conn, cur).insert_user(js_code_result["openid"])
            
            user_info = WxUserTableMethods(conn, cur).get_user_by_open_id(js_code_result["openid"])

        # Generate a token for the user
        wx_login_methods = WxTokenTableMethods(conn, cur)

        token_content = wx_login_methods.insert_token(user_info["user_id"])

        js_code_result["token"] = token_content

        js_code_result["user_id"] = user_info["user_id"]
        js_code_result["phone_number"] = user_info["phone_number"]
        js_code_result["unionid"] = user_info["unionid"]


        del js_code_result["session_key"] # remove the session_key from the response
        
        print(js_code_result)
        args_success = {
            "status": 1,
            "errorCode": None,
            "errorMsg": None,
            "resultBody":  js_code_result
        }

        return jsonify(args_success)

        
@wx_login_blueprint.route('/tt_get_user_phone', methods=['POST'])
def tt_get_user_phone():

    # Get the required arguments from the request

    code = request.form.get('code')
    openid = request.form.get('openid')

    # Check if the required arguments are present
    if not code or not openid:
        args_error = {
            "status": -1,
            "errorCode": 1001,
            "errorMsg": "code and openid are required",
            "resultBody": None

        }

        return jsonify(args_error)
    
    # Check if the user exists in the database
    with PostgreSingleton() as conn:
        cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) # cursor for executing queries
        wx_access_token = WxAccessTokenTableMethods(conn, cur)
        
        phone_number_result = wx_access_token.get_user_phone_number(code, openid)

        if not phone_number_result:
            args_error = {
                "status": -1,
                "errorCode": 1002,
                "errorMsg": "get_user_phone_number API call failed",
                "resultBody": phone_number_result
            }

            return jsonify(args_error)

        
        args_success = {
            "status": 1,
            "errorCode": None,
            "errorMsg": None,
            "resultBody":  phone_number_result
        }

        return jsonify(args_success)
    

@wx_login_blueprint.route('/update_user_info', methods=['POST'])
def update_user_info():
    '''update_user(self, open_id, wx_name=None, wx_avatar=None, wx_id=None):'''

    # Get the required arguments from the request

    open_id = request.form.get('open_id')
    wx_name = request.form.get('wx_name')
    wx_avatar = request.form.get('wx_avatar')
    wx_id = request.form.get('wx_id')

    # Check if the required arguments are present
    if not open_id or not wx_name or not wx_avatar or not wx_id:
        args_error = {
            "status": -1,
            "errorCode": 1001,
            "errorMsg": "open_id, wx_name, wx_avatar, wx_id are required",
            "resultBody": None

        }

        return jsonify(args_error)
    
    # Check if the user exists in the database
    with PostgreSingleton() as conn:
        cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) # cursor for executing queries
        wx_user_table_methods = WxUserTableMethods(conn, cur)
        
        wx_user_table_methods.update_user(open_id, wx_name, wx_avatar, wx_id)

        args_success = {
            "status": 1,
            "errorCode": None,
            "errorMsg": None,
            "resultBody":  "User updated successfully"
        }

        return jsonify(args_success)

# def get_wxa_code(self, path="pages/index/index", env_version="trial", params={}, filename="code.png"):

@wx_login_blueprint.route('/get_wxa_code', methods=['POST'])

def get_wxa_code():
    '''get_wxa_code(self, path="pages/index/index", env_version="trial", params={}, filename="code.png"):'''

    # Get the required arguments from the request

    path = request.form.get('path', "pages/index/index")
    env_version = request.form.get('env_version', "trial")
    recommend_user_id = request.form.get('recommend_user_id')

    
    # filename = request.form.get('filename')

    # Check if the required arguments are present
    if not path or not env_version or not recommend_user_id:
        args_error = {
            "status": -1,
            "errorCode": 1001,
            "errorMsg": "recommend_user_id is required",
            "resultBody": None

        }

        return jsonify(args_error)
    
    params = {
        "recommend_user_id": recommend_user_id
    }

    filename = f"{recommend_user_id}_wxa_code.png"
    
    # Check if the user exists in the database
    with PostgreSingleton() as conn:
        cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) # cursor for executing queries
        wx_login_methods = WxAccessTokenTableMethods(conn, cur)
        
        wxa_code_result = wx_login_methods.get_wxa_code(path, env_version, params, filename)

        if not wxa_code_result:
            args_error = {
                "status": -1,
                "errorCode": 1002,
                "errorMsg": "get_wxa_code API call failed",
                "resultBody": wxa_code_result
            }
            return jsonify(args_error)
        
        args_success = {
            "status": 1,
            "errorCode": None,
            "errorMsg": None,
            "resultBody":  f"https://tt.bainarm.cn/tt/api/view/{filename}"
        }

        return jsonify(args_success)

